/**
 * 
 */
package com.imonsoft.common.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.core.CollectionFactory;

/**
 * 
 * @author LiQianHui
 * @date 2013-04-17
 * @version 2013
 */
public abstract class RequestUtil {

	/**
	 * ip校验
	 * 
	 * @param s
	 * @return
	 */
	public static Boolean isIpAddress(String s) {
		String regex = "(((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))[.](((2[0-4]\\d)|(25[0-5]))|(1\\d{2})|([1-9]\\d)|(\\d))";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(s);
		return m.matches();
	}

	/**
	 * 获取客户端ip
	 * 
	 * @param request
	 * @return
	 */
	public static String getClientAddress(HttpServletRequest request) {
		String address = request.getHeader("X-Forwarded-For");
		if (address != null && isIpAddress(address)) {
			return address;
		}
		return request.getRemoteAddr();
	}

	/**
	 * 取得客户端的系统版本
	 * 
	 * @param request
	 * @return
	 */
	public static String getUserAgent(HttpServletRequest request) {
		return request.getHeader("User-Agent");
	}

	/**
	 * 取得客户端的主机名
	 * 
	 * @param request
	 * @return
	 */
	public static String getRemoteHost(HttpServletRequest request) {
		return request.getRemoteHost();
	}

	/**
	 * 取得客户端的端口
	 * 
	 * @param request
	 * @return
	 */
	public static int getRemotePort(HttpServletRequest request) {
		return request.getRemotePort();
	}

	/**
	 * 取得客户端的用户
	 * 
	 * @param request
	 * @return
	 */
	public static String getRemoteUser(HttpServletRequest request) {
		return request.getRemoteUser();
	}

	/**
	 * 
	 * @param request
	 * @param name
	 * @return 返回值为null时转换为空串""
	 */
	public static String getString(HttpServletRequest request, String name) {
		String value = request.getParameter(name);
		return value == null ? "" : value;
	}

	public static String getString(HttpServletRequest request, String name, String defaultValue) {
		String value = request.getParameter(name);
		return value == null || "".equals(value) ? defaultValue : value;
	}

	public static String getIso2GbkString(HttpServletRequest request, String name, String defaultValue) {
		String value = request.getParameter(name);
		return value == null || "".equals(value) ? defaultValue : StringUtil.iso2gbk(value);
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	public static Map<String, String> getParameterMap(HttpServletRequest request) {
		Enumeration<?> enumeration = request.getParameterNames();
		Map<String, String> map = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(1);
		while (enumeration.hasMoreElements()) {
			String element = (String) enumeration.nextElement();
			// request.getParameterValues(element);
			map.put(element, request.getParameter(element));
		}
		return map;
	}

	@SuppressWarnings({ "unchecked", "deprecation" })
	public static Map<String, String> getParameterIso2UtfMap(HttpServletRequest request) {
		Enumeration<?> enumeration = request.getParameterNames();
		Map<String, String> map = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(1);
		while (enumeration.hasMoreElements()) {
			String element = (String) enumeration.nextElement();
			// request.getParameterValues(element);
			map.put(element, StringUtil.iso2utf(request.getParameter(element)));
		}
		return map;
	}

	/**
	 * 将{key1:[v11,v12,...],key2:[v21,v22,...],...}组装到Bean[{key1:v11,
	 * key2:v12,...},{key1:v12,key2:v22,...},...]
	 * 
	 * @param <T>
	 * @param request
	 * @param beanClass
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "deprecation", "rawtypes" })
	public static <T> List<T> populateBeans(HttpServletRequest request, Class<T> beanClass, String[] excludeFields) {
		List<T> list = null;
		List<Map<String, String>> valuesList = null;
		if (beanClass != null) {
			Field beanField[] = beanClass.getDeclaredFields();
			int fieldSize = beanField.length;
			for (Field field : beanField) {
				String fieldName = field.getName();
				String[] values = request.getParameterValues(fieldName);
				if (values == null) {
					continue;
				}
				if (excludeFields != null) {
					boolean isContinue = false;
					for (String excludeField : excludeFields) {
						if (fieldName.equals(excludeField)) {
							isContinue = true;
							break;
						}
					}
					if (isContinue) {
						continue;
					}
				}
				int size = values.length;
				if (valuesList == null) {
					valuesList = new ArrayList<Map<String, String>>(size);
					for (int i = 0; i < size; i++) {
						Map<String, String> map = CollectionFactory.createLinkedCaseInsensitiveMapIfPossible(fieldSize);
						valuesList.add(map);
					}
				}
				if (list == null) {
					list = new ArrayList<T>(size);
				}
				for (int i = 0; i < size; i++) {
					Map<String, String> map = valuesList.get(i);
					map.put(fieldName, values[i]);
				}
			}
			for (Map<String, String> map : valuesList) {
				try {
					Collection<String> values = map.values();
					boolean hasValues = false;
					for (String value : values) {
						if (value != null && value.length() > 0) {
							hasValues = true;
						}
					}
					if (!hasValues) {
						continue;
					}
					T bean = beanClass.newInstance();
					BeanUtils.populate(bean, map);
					list.add(bean);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return list == null ? new ArrayList(0) : list;
	}

	/**
	 * 判断是否为ajax请求
	 * 
	 * @param request
	 * @return true为ajax语法，false为其它。
	 */
	public static boolean isAjaxRequest(HttpServletRequest request) {
		if (request != null) {
			String requestType = request.getHeader("X-Requested-With");
			if (requestType != null && "XMLHttpRequest".equals(requestType)) {
				return true;
			}
		}
		return false;
	}
}
